package org.dant.ant.extension.tasks.internal;

import java.net.*;
import java.io.*;

import org.dant.ant.extension.net.RemoteHelper;
import org.dant.ant.extension.net.NetConstants;

public class Endpoint implements Serializable {

  protected static String ip = NetConstants.DEFAULT_LOCAL_IP;
  protected static String hostname = NetConstants.DEFAULT_LOCAL_HOST;
  protected String port = Integer.toString(NetConstants.DEFAULT_RMI_PORT);
  protected String protocol = NetConstants.DEFAULT_PROTOCOL;
  protected String path = NetConstants.DEFAULT_PATH;
  protected String fullurl = null;
  protected String networking = null;
  protected File basedir = null;
  protected RemoteHelper rhelper = null;

  static {
    try {
      hostname = InetAddress.getLocalHost().getHostName();
      ip = InetAddress.getLocalHost().getHostAddress();

      if ("127.0.0.1".equals(ip) && hostname != null) {
          InetAddress[] addresses = InetAddress.getAllByName(hostname);
          for (int i=0; i<addresses.length; i++) {
              if (!"127.0.0.1".equals(addresses[i].getHostAddress())) {
                  ip = addresses[i].getHostAddress();
                  break;
              }
          }
      }
    } catch (java.net.UnknownHostException e) {
      e.printStackTrace();
    }
  }

  public Endpoint() {}

  public Endpoint(String hostname, String ip, String port, String networking, File basedir) {
    setHostname(hostname);
    setIp(ip);
    setPort(port);
    setNetworking(networking);
    setBaseDir(basedir);

    resolveProtocol();
  }

  public Endpoint(String fullpath) {
    parse(fullpath);
  }
  

  private void resolveProtocol() {
    try {
      System.out.println("Networking facility class: " + getNetworking());
      rhelper = (RemoteHelper) Class.forName(getNetworking()).newInstance();
    } catch (Exception cnfe) {
      //      cnfe.printStackTrace();
      rhelper = null;
      return;
    }
    
    setProtocol(rhelper.getProtocol());
    setPath(rhelper.getPath());
  }

  public void setBaseDir(File basedir) {
    this.basedir = basedir;
  }

  public File getBaseDir() {
    return this.basedir;
  }
  
  public String getNetworking() {
    return (networking != null) ? networking : "org.dant.ant.extension.net.rmi.RMIHelper";
  }

  public RemoteHelper getRemoteHelper() {
    return rhelper;
  }

  public void setNetworking(String clz) {
    this.networking = clz;
  }
  
  public String getFullURL() {
    if (fullurl != null) 
      return fullurl;
    else if (!"127.0.0.1".equals(this.ip))
      return getIPEndpoint();
    else
      return getHostEndpoint();
  }

  public void setFullURL(String url) {
    this.fullurl = url;
  }

  public static String getLocalhost() {
      String host = ip;
      try {
          host = InetAddress.getLocalHost().getHostAddress();
          if (host == null || "127.0.0.1".equals(host)) {
              host = InetAddress.getLocalHost().getHostName();
          }
      } catch (java.net.UnknownHostException e) {
          e.printStackTrace();
    }
      return host;
  }
    
  public void setIp(String ip) {
    this.ip = ip;
  }

  public void setHostname(String hostname) {
    this.hostname = hostname;
  }

  public void setPort(String port) {
    this.port = port;
  }

  public void setProtocol(String protocol) {
    this.protocol = protocol;
  }

  public void setPath(String path) {
    this.path = path;
  }

  public String getIp() {
    return this.ip;
  }

  public String getHostname() {
    return this.hostname;
  }

  public String getPort() {
    return this.port;
  }

  public String getPath() {
    return this.path;
  }

  public String getIPEndpoint() {
    return constructEndPoint(this.ip, this.port);
  }

  public String getHostEndpoint() {
    return constructEndPoint(this.hostname, this.port);
  }

  public String constructEndPoint(String host, String port){
    StringBuffer sb = new StringBuffer();
    sb.append(protocol);
    sb.append(host);
    sb.append(":");
    sb.append(port);
    sb.append("/");
    sb.append(path);
    return sb.toString();
  }

  public String toString() {
    return getFullURL();
  }

  private void parse(String path) {
    try {
      URL url = new URL(path);
      this.protocol = url.getProtocol();
      this.hostname = url.getHost();
      this.port = url.getPort()+"";
      this.path = url.getPath();
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
  }
}

